/* -*- C -*- */
/*
 * Copyright (c) 2020, ASR microelectronics
 * All rights reserved.
 */

#ifndef SPI_ARCH_H_
#define SPI_ARCH_H_
#include <stdint.h>
#include <stdbool.h>
#include "lv_drv_conf.h"

#if LCD_GENERIC_SPI

#define SPI_DMA_MAX_SIZE     0x1ff8

typedef enum {
  SPI_BUS_SSP0,
  SPI_BUS_SSP1,
  SPI_BUS_SSP2,
  SPI_BUS_NUM
} spi_bus_t;

typedef enum {
  SPI_MODE_0 = 0,           /**< CPOL=0, CPHA=0 */
  SPI_MODE_1,               /**< CPOL=0, CPHA=1 */
  SPI_MODE_2,               /**< CPOL=1, CPHA=0 */
  SPI_MODE_3                /**< CPOL=1, CPHA=1 */
} spi_mode_t;

typedef enum {
  SPI_CLK_6500KHZ = 0,
  SPI_CLK_13MHZ,
  SPI_CLK_26MHZ,
  SPI_CLK_52MHZ,
  SPI_CLK_3250KHZ,
  SPI_CLK_1625KHZ,
  SPI_CLK_812500HZ,
  SPI_CLK_1MHZ,
  SPI_CLK_MAX,
} spi_clk_t;

typedef enum {
  SPI_3_WIRE_MODE,
  SPI_4_WIRE_MODE,
} spi_wire_mode_t;

typedef enum {
  SPI_DIR_TX,
  SPI_DIR_RX,
} spi_dir_t;

typedef enum {
  XFER_MODE_POLL,
  XFER_MODE_IRQ,
  XFER_MODE_DMA,
} xfer_mode_t;

typedef struct {
  spi_bus_t bus;
  spi_clk_t clk;
  spi_mode_t spi_mode;
  spi_wire_mode_t wire_mode;
  int cs_pin;
  const uint32_t *mfp_cfg;
} spi_param_t;

typedef void (*spi_complete_cb_t)(void *arg);
int spi_register_complete_cb(spi_bus_t bus, spi_complete_cb_t cb, void *arg);
int spi_transfer_bits(spi_bus_t bus, bool cont, const void *out, void *in, size_t bits, xfer_mode_t mode);
int spi_transfer_bytes(spi_bus_t bus, bool cont, const void *out, void *in, size_t len, xfer_mode_t mode);
int spi_arch_init(spi_param_t *arg);

int spi_set_clk(spi_bus_t bus, spi_clk_t clk);
int spi_set_dir(spi_bus_t bus, spi_dir_t dir);
int spi_chip_select(spi_bus_t bus, int state);

#endif /* LCD_GENERIC_SPI */

#endif /* SPI_ARCH_H_ */
